/**
 * 
 */
package kernel_gui.gui.extended;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.Timer;

import common.entities.nonpersistent.GameQuestion;


/**
 * @author Yoyo
 *
 */
public class EPlayGameFrame extends kernel_gui.gui.generic.graphic.PlayGameFrame {

	
	/**
	 * 
	 */
	private static final long serialVersionUID = -5128102090942724917L;
	
	/*Question var*/
	private int currentQuestionNumber = 1;
	private GameQuestion currentGameQuestion = null;
	private int selectedAnswer = -1;
	private JRadioButton selectedRadioButton = null;
	boolean extraTimeWheelUsed = false;
	boolean fiftyFiftyWheelUsed = false;
	boolean replaceQuestionWheelUsed = false;
	private static int QUESTION_TIME = 31; 
	
	/*Stage var*/
	private int currentStage = 1;
	private final int stage1HighRange = 5;
	private final int stage2HighRange = 10;
	//private final int stage3HighRange = 15; - not needed
	
	/*Money var*/
	private int currentMoney = 0;
	private final int stage1FallingToMoney = 0;
	private final int stage2FallingToMoney = 1000;
	private final int stage3FallingToMoney = 32000;
	
	
	/*Messages to user*/
	private final String[] rightAnswersResponses = new String[] {"That is right!", "Hooo, you smart aren't ya?", "Fuckkk, you are RIGHT!",
			"You are rocking tonight are you?", "That is true.", "You are rocking baby!", "My mother could answer that also", "My dog can answer it",
			"Even I didn't know it", "!!!WoWoWoWoWoWoWoWo!!!", "And your teacher in high-school thought that you're dumb..."};
	
	private final String[] wrongAnswersResponses = new String[] {"You are WRONG!", "That is wrong.", "I'm sorry to tell you\nBUT THIS IS WRONG!"};
	
	/*Timer action listener*/
 	private Timer countDownClock = null;
 	private boolean FLAG_timeRanOut = false;
 	private boolean FLAG_showingOtherMSG = false;
	
	public EPlayGameFrame() {
		super(kernel.isAdministrator());
		
		
		setExecuteOnCancel(new CommandToExecute() {
			@Override
			public void command(Object answer) {
				Component components[] = MainPanel.getComponents();
				for (Component c : components) {
					if(c instanceof JPanel){
						JPanel panel = (JPanel) c;
						Component pcomponents[] = panel.getComponents();
						for(Component pc : pcomponents){
							pc.setEnabled(true);
						}
					}else
						c.setEnabled(true);
				}
				NextQButton.setEnabled(false);
			}
		});
		
		setExecuteBeforeLongRequest(new CommandToExecute() {
			
			@Override
			public void command(Object answer) {
				Component components[] = MainPanel.getComponents();
				for (Component c : components) {
					if(c instanceof JPanel){
						JPanel panel = (JPanel) c;
						Component pcomponents[] = panel.getComponents();
						for(Component pc : pcomponents){
							pc.setEnabled(false);
						}
					}else
						c.setEnabled(false);
				}
			}
		});
		
		AdminAnswerButton.setVisible(false);
		if(kernel.isAdministrator()){
			int userClicked = JOptionPane.showConfirmDialog(this, "ADMIN: do you want the" +
				" 'Get Answer' button?", "Yes = Cheater!", JOptionPane.YES_NO_OPTION);
			AdminAnswerButton.setVisible(true);
			if(userClicked == JOptionPane.YES_OPTION){
				AdminAnswerButton.setEnabled(true);
			}else{
				AdminAnswerButton.setEnabled(false);
			}
		}
		if(EPlayGameFrame.kernel.hasNextQuestion()){
			resetTimer();
			currentGameQuestion = EPlayGameFrame.kernel.nextQuestion();
			updateQuestionToScreen(EPlayGameFrame.this.currentGameQuestion);
		}
			
	}

	protected void onTimeOut(){
		if(!FLAG_showingOtherMSG){
			if(selectedAnswer == -1){/*And the user hasn't selected a message*/
				JOptionPane.showMessageDialog(this, "You ran out of time!" +
						"And without choosing an answer\nmeans, Bye Bye!");
				endGame(false,true);
			}else{/*The user has selected an answer*/
				JOptionPane.showMessageDialog(this, "You ran out of time!" +
						"Lets see if your answer is right..");
				validateChoosenAnswer();
			}
		}else{
			countDownClock.stop();
			FLAG_timeRanOut = true;
		}
	}
	
	private void updateQuestionToScreen(GameQuestion gq){
		
		/*Update question counter (memory and label)*/
		if(currentQuestionNumber < 10)/*Pad one zero if necessary*/
			CurrentQLabel.setText("0"+currentQuestionNumber);
		else
			CurrentQLabel.setText(String.valueOf(currentQuestionNumber));
		
		/*Update stage counter (memory and label)*/
		if(currentQuestionNumber <= stage1HighRange){
			currentStage = 1;
			StageLabel.setText("$0");
		}else if(currentQuestionNumber <= stage2HighRange){
			currentStage = 2;
			StageLabel.setText("$1,000");
		}else{ /*if(currentQuestionNumber <= stage3HighRange)*/
			currentStage = 3;
			StageLabel.setText("$32,000");
		}
		
		/*clear the screen from previous question leftovers*/
		
		
		Ans1RadioButton.setForeground(TimeLeftHeaderLabel.getForeground());
		Ans2RadioButton.setForeground(TimeLeftHeaderLabel.getForeground());
		Ans3RadioButton.setForeground(TimeLeftHeaderLabel.getForeground());
		Ans4RadioButton.setForeground(TimeLeftHeaderLabel.getForeground());
		AnswerButtonGroup.clearSelection();
		NextQButton.setEnabled(false);
		
		selectedAnswer = -1;
		selectedRadioButton = null;
		
		if(fiftyFiftyWheelUsed){
			Ans1RadioButton.setEnabled(true);
			Ans2RadioButton.setEnabled(true);
			Ans3RadioButton.setEnabled(true);
			Ans4RadioButton.setEnabled(true);
		}
		
		/*Update current Question data*/
		QuestionHeaderLabel.setText(String.format("For %s,", currency_nf.format(gq.getQuestionValue())));
		QuestionLabel.setText(parseStringIntoFixedSize(6, 94, gq.toString()));
		Ans1RadioButton.setText(parseStringIntoFixedSize(1, 92, gq.getAnswers()[0]));
		Ans2RadioButton.setText(parseStringIntoFixedSize(1, 92, gq.getAnswers()[1]));
		Ans3RadioButton.setText(parseStringIntoFixedSize(1, 92, gq.getAnswers()[2]));
		Ans4RadioButton.setText(parseStringIntoFixedSize(1, 92, gq.getAnswers()[3]));
		
		/*Start the timer*/
		countDownClock.start();
	}

	
	
	
	@Override
	protected void NextQButtonActionPerformed(ActionEvent evt) {
		Random r = new Random();
		boolean willPromptToUser = (r.nextInt(3) == 0) ? true : false;
		if(willPromptToUser){
			FLAG_showingOtherMSG = true;
			int isHeSure = JOptionPane.showConfirmDialog(this, "Are You Sure?", "Are You Sure?",
					JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
			FLAG_showingOtherMSG = false;
			if(isHeSure == JOptionPane.NO_OPTION){
				if(FLAG_timeRanOut){
					FLAG_timeRanOut = false;
					onTimeOut();
				}
				return;
			}
		}
		

		
		validateChoosenAnswer();
		
	}
	
	private void resetTimer(){
		TimeLabel.setForeground(TimeLeftHeaderLabel.getForeground());
		countDownClock = new Timer(1000, new ActionListener() {
	 		int timeLeft = QUESTION_TIME;
			  
		      public void actionPerformed(ActionEvent evt) {
				  
		    	  timeLeft--;
		    	  
		    	  if(timeLeft < 10){/*pad time with 0 if needed*/
		    		  EPlayGameFrame.this.TimeLabel.setText("0"+String.valueOf(timeLeft));
		    		  EPlayGameFrame.this.TimeLabel.setForeground(new Color(Color.RED.getRGB()));
		    	  }
		    	  else
		    		  EPlayGameFrame.this.TimeLabel.setText(String.valueOf(timeLeft));
		    	  
		    	  if(timeLeft == 0){
		    		  EPlayGameFrame.this.TimeLabel.setForeground(new Color(Color.BLACK.getRGB()));
		    		  EPlayGameFrame.this.onTimeOut();
		    	  }
		      }
		});
	}
	
	private void validateChoosenAnswer(){
		/*Submit user answer*/
		countDownClock.stop();
		resetTimer();
		boolean wasHeRight = kernel.submitAnswer(selectedAnswer);
		if(wasHeRight){
			if(kernel.hasNextQuestion()){
				/*tell him he was right - probability of showing the message 1/2*/
				Random r = new Random();
				if(r.nextBoolean())
					JOptionPane.showMessageDialog(this, randomAfterChoosenAnswerMSG(true));
				
				currentMoney = currentGameQuestion.getQuestionValue();
				/*the game continues*/
				currentQuestionNumber++;
				currentGameQuestion = kernel.nextQuestion();
				updateQuestionToScreen(currentGameQuestion);
			}else{
				/*finished game*/
				currentMoney = currentGameQuestion.getQuestionValue();
				JOptionPane.showMessageDialog(this, "You won $1,000,000, but they are virtual\nso good luck with them!");
				endGame(false, false);
			}
		}else{/*he was wrong*/
			/*update his money to current stage falling-to-money*/
			switch(currentStage){
			case 1:
				currentMoney = stage1FallingToMoney;
				break;
			case 2:
				currentMoney = stage2FallingToMoney;
				break;
			case 3:
				currentMoney = stage3FallingToMoney;
				break;
			}
			
			JOptionPane.showMessageDialog(this, randomAfterChoosenAnswerMSG(false));
			endGame(false,false);
		}
	}

	private String randomAfterChoosenAnswerMSG(boolean right){
		Random r = new Random();
		int msgIndx;
		if(right){
			msgIndx = r.nextInt(rightAnswersResponses.length);
			return "You Are Right!\n"+rightAnswersResponses[msgIndx];
		}else/*wrong*/{
			msgIndx = r.nextInt(wrongAnswersResponses.length);
			return (wrongAnswersResponses[msgIndx] + " \nBut you did win: " + currency_nf.format(currentMoney));
		}
	}
	
	private void endGame(boolean itWasUserChoice, boolean displayEndMoney) {
		if(itWasUserChoice){
			FLAG_showingOtherMSG = true;
			int isHeSure = JOptionPane.showConfirmDialog(this, "If you leave the game now you will win " + 
					currency_nf.format(currentMoney) + "\n" + "but you can leave now and always think about\n" +
					"the time you threw " + currency_nf.format(currentGameQuestion.getQuestionValue()) +" away!\n" +
							"so, you sure?", "Don't Leave!!!", JOptionPane.YES_NO_OPTION);
			if(isHeSure == JOptionPane.NO_OPTION){
				FLAG_showingOtherMSG = false;
				if(FLAG_timeRanOut){
					FLAG_timeRanOut = false;
					onTimeOut();
				}
				return;
			}
		}
		
		/*ending game*/
		countDownClock.stop();
		if(displayEndMoney){
			JOptionPane.showMessageDialog(this, "You won " + currency_nf.format(currentMoney));
		}
		int requestID = executeBeforeLongRequest(new CommandToExecute() {
			
			@Override
			public void command(Object answer) {
				/*finished game, go back to main menu*/
				EPlayGameFrame.this.openAnotherFrame(EMainMenuFrame.class, true);
			}
		});
		
		kernel.endGame(requestID);

	}
	

	@Override
	protected void LeaveGameButtonActionPerformed(ActionEvent evt) {
		endGame(true, true);
	}
	
	@Override
	protected void Ans1RadioButtonActionPerformed(ActionEvent evt) {
		OnRadioButtonSelection(Ans1RadioButton, 0);
		selectedAnswer = 0;
	}
	
	@Override
	protected void Ans2RadioButtonActionPerformed(ActionEvent evt) {
		OnRadioButtonSelection(Ans2RadioButton, 1);
		selectedAnswer = 1;
	}
	
	@Override
	protected void Ans3RadioButtonActionPerformed(ActionEvent evt) {
		OnRadioButtonSelection(Ans3RadioButton, 2);
	}
	
	@Override
	protected void Ans4RadioButtonActionPerformed(ActionEvent evt) {
		OnRadioButtonSelection(Ans4RadioButton, 3);
	}

	private void OnRadioButtonSelection(JRadioButton newlySelectedRadioButton, int newlySelectedAnswer){
		if(selectedRadioButton != null){
			selectedRadioButton.setForeground(TimeLeftHeaderLabel.getForeground());
		}
		
		if(selectedAnswer == -1)/*this is the first answer that we are choosing*/
			NextQButton.setEnabled(true);
		
		selectedRadioButton = newlySelectedRadioButton;
		
		selectedRadioButton.setForeground(Color.BLUE);
		selectedAnswer = newlySelectedAnswer;
		selectedRadioButton.setSelected(true);
		
	}
	
	@Override
	protected void AdminAnswerButtonActionPerformed(ActionEvent evt) {
		switch(currentGameQuestion.getRightAnswerIndex()){
		case 0:
			OnRadioButtonSelection(Ans1RadioButton,0);
			break;
		case 1:
			OnRadioButtonSelection(Ans2RadioButton,1);
			break;
		case 2:
			OnRadioButtonSelection(Ans3RadioButton,2);
			break;
		case 3:
			OnRadioButtonSelection(Ans4RadioButton,3);
			break;
		}
	}

	@Override
	protected void ExtraTimeWheelLabelMouseClicked(MouseEvent evt) {
		if(!extraTimeWheelUsed){
			//currenty i'm not using the extra time given from kernel, just restarting, is it ok?
			//int kerExtraTime = kernel.helpWheelExtraTime();
			kernel.helpWheelExtraTime();
			countDownClock.stop();
			resetTimer();
			countDownClock.start();
			
			extraTimeWheelUsed = true;
			ExtraTimeWheelLabel.setEnabled(false);
		}
	}
	
	@Override
	protected void FiftyFiftyWheelLabelMouseClicked(MouseEvent evt) {
		if(!fiftyFiftyWheelUsed){
			int[] wrongAnswersToDisable = kernel.helpWheelFiftyFifty();
			for(Integer i : wrongAnswersToDisable){
				switch(i){
				case 0:
					Ans1RadioButton.setEnabled(false);
					break;
				case 1:
					Ans2RadioButton.setEnabled(false);
					break;
				case 2:
					Ans3RadioButton.setEnabled(false);
					break;
				case 3:
					Ans4RadioButton.setEnabled(false);
					break;
				}
			}
			
			fiftyFiftyWheelUsed = true;
			FiftyFiftyWheelLabel.setEnabled(false);
		}
	}
		
	@Override
	protected void ReplaceQuestionLabelMouseClicked(MouseEvent evt) {
		if(!replaceQuestionWheelUsed){
			currentGameQuestion = kernel.helpWheelReplaceQuestion();
			updateQuestionToScreen(currentGameQuestion);
			
			replaceQuestionWheelUsed = true;
			ReplaceQuestionLabel.setEnabled(false);
		}
		
	}

	@Override
	protected void setWindowComponentsWhenCalledFromAnotherFrame() {
		/*not needed*/		
	}

	@Override
	protected void BackButtonActionPerformed(ActionEvent evt) {
		endGame(true, true);
		
	}


}
